<?php

namespace App\Commons\Domain\Module\Exchange\Traits;

use App\Commons\Domain\Module\Exchange\Entity\AdvertisingEntity;
use App\Commons\Domain\Module\Exchange\Model\AdPayment;
use App\Commons\Domain\Module\Financial\Model\Payment;
use App\Commons\Domain\Module\Financial\Model\Wallet;
use App\Commons\Domain\Module\UserCenter\Model\Member;
use Arr;

trait AdTrait
{
    /**
     * 创建广告
     * @param Member $member
     * @param int $coin_id 币种id
     * @param int $type 广告类型：1卖出，2买入
     * @param float $quantity 数量
     * @param float $price 单价
     * @param array $data 其他数据:['min_limit'=>100, 'max_limit'=>100, 'pay_time_limit'=>5, 'remark','country_id','payment'=>1];
     * @return mixed
     */
    public function createAd(Member $member, int $coin_id, int $type, float $quantity, float $price, array $data)
    {
        return db_trans(function () use ($data, $price, $quantity, $type, $coin_id, $member) {
            // 获取钱包信息
            $wallet = Wallet::where(['uid' => $member->uid, 'coin_id' => $coin_id])->firstOrFail();

            // 卖币广告检查用户钱包余额，并进行金额冻结
            if ($type === 1) {
                $this->ctx->FinancialService->freeze($wallet->id, $quantity);
            }

            // 检查对应的收付款方式
            throw_on(!Payment::where(['uid' => $member->uid, 'type' => $data['pay_type']])->first(), 0xf00361);

            // 创建广告
            return app(AdvertisingEntity::class)->createAd($member->uid, $wallet->id, $price, $quantity, $type, $data);
        });
    }

    /**
     * 修改更新广告：为保持数据一致性有处于交易中订单的广告不能修改
     * @param Member $member
     * @param int $ad_id
     * @param array $data
     * @return
     */
    public function updateAd(Member $member, int $ad_id, array $data)
    {
        return db_trans(function () use ($member, $data, $ad_id) {
            $ad = app(AdvertisingEntity::class)->whereId($ad_id)->firstOrFail();
            // 非下架的广告不能修改
            throw_on($ad['status'] !== 2, 0xf00422);
            // 卖币广告，涉及数量修改的，对应用户账户币种数量也要修改
            if ($ad['type'] === 1 && Arr::exists($data, 'quantity') && $data['quantity'] - $ad['quantity'] !== 0) {
                // 获取钱包信息
                $wallet = Wallet::where(['uid' => $member->uid, 'coin_id' => $ad['coin_id']])->firstOrFail();

                if ($data['quantity'] > $ad['quantity']) {
                    // 增加广告数量
                    $this->ctx->FinancialService->freeze($wallet->id, $data['quantity'] - $ad['quantity']);
                } elseif ($data['quantity'] < $ad['quantity']) {
                    // 减少广告数量
                    $this->ctx->FinancialService->freedFreeze($wallet->id, $data['quantity'] - $ad['quantity']);
                }
            }
            return app(AdvertisingEntity::class)->updateAd($ad_id, $data);
        });
    }

    /**
     * 上架、下架和关闭广告：
     * 关闭的广告不能再修改状态，只能重新创建新的广告
     * 上架和下架仅单纯的改变状态，关闭卖币广告释放冻结资金，
     * @param int $ad_id
     * @param int $status
     * @return mixed
     */
    public function upDown(int $ad_id, int $status)
    {
        $ad = app(AdvertisingEntity::class)->whereId($ad_id)->firstOrFail();
        // 已经关闭的广告不能修改
        throw_on($ad['status'] === 3, 0xf00322);

        return db_trans(function () use ($ad, $status) {
            // 关闭广告释放冻结金额
            if ($status === 3 && $ad['type'] === 1) {
                $wallet = Wallet::where(['uid' => $ad->uid, 'coin_id' => $ad->coin_id])->firstOrFail();
                $this->ctx->FinancialService->freedFreeze($wallet->id, $ad->quantity);
            }
            return app(AdvertisingEntity::class)->upDown($ad->id, $status);
        });
    }
}
